package algo3.g203.modelo.armas;

import java.util.ArrayList;
import java.util.List;

import fiuba.algo3.titiritero.modelo.ObjetoPosicionable;
import fiuba.algo3.titiritero.modelo.ObjetoVivo;

import algo3.g203.modelo.armas.explosiones.ExplosionBehavior;
import algo3.g203.modelo.armas.explosiones.Fragmento;
import algo3.g203.modelo.fisica.Posicion;
import algo3.g203.modelo.naves.Nave;

public abstract class Arma implements ObjetoVivo, ObjetoPosicionable {
	
	protected Posicion posicion;
	protected List<ObservadorDeArma> listaObservadores;
	protected boolean yaExploto;
	
	public Arma(Posicion p) {
		this.posicion = p;
		this.listaObservadores = new ArrayList<ObservadorDeArma>();
		this.yaExploto = false;
	}

	/**
	 * Hace explotar la mina
	 * @return una lista con los fragmentos arrojados por la explosion
	 */
	public List<Fragmento> performExplosion() {
		this.yaExploto = true;
		return this.getExplosionBehavior().explotar(this.posicion);
	}
	
	/**
	 * @return true si el arma ya estallo
	 */
	public boolean yaExploto() {
		return this.yaExploto;
	}
	
	/**
	 * Define quien va a escuchar la explosion del arma
	 * @param o : observador
	 */
	public void agregarObservador(ObservadorDeArma o) {
		this.listaObservadores.add(o);
	}
	
	/**
	 * TEMPLATE METHOD : El arma tiene que decidir que hacer una vez que comienza un nuevo turno
	 * 
	 * @return : true si el arma exploto en este turno!
	 */
	public abstract boolean comenzarTurno();
	
	/**
	 * TEMPLATE METHOD : Devolver el costo de disparar el arma
	 */
	abstract public int getCosto();
	/**
	 * TEMPLATE METHOD : Devolver la forma en que explotara el arma
	 */
	protected abstract ExplosionBehavior getExplosionBehavior();
	/**
	 * DOUBLE DISPATCH : Danio a nave poliformico segun tipo de nave y arma
	 * @param n : Tipo de nave a la que daniara el arma
	 */
	public abstract void daniar(Nave n);
	
	// COSAS PARA TITIRITERO
	
	@Override
	public int getX() {
		return (50*this.posicion.getCoordenadaX());
	}

	@Override
	public int getY() {
		return (50*this.posicion.getCoordenadaY());
	}
	
	public void vivir(){}

}
